package com.bjh.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.CountDownLatch;

@Slf4j
@Configuration
public class ZookeeperConfig {


    private  String connectString = "127.0.0.1:2181";

    //毫秒
    private  int timeout = 4000;

    /**
     * connectString:连接服务器的ip字符串,多个ip用逗号分隔
     * sessionTimeout:超时时间,心跳收不到了,那就超时
     * watcher:通知时间,如果有对应的事件触发,则会收到一个通知:如果不需要,那就设置为null
     * canBeReadOnly:可读,当这个物理机节点断开后,还是可以读到数据的,
     *              只是不能写,此时数据被读取到的可能是旧数据,此处建议设置为false,不推荐使用
     * sessionId:会话的id
     * sessionPasswd:会话密码 当会话丢失后,可以依据sessionId和sessionPasswd重新获取会话
     * @return
     */
    @Bean(name = "zkClient")
    public ZooKeeper zkClient(){
        ZooKeeper zooKeeper=null;
        try {
            //使一个线程等待其他线程各自执行完毕后在执行
            //使用在这边,zk连接需要时间,等待连接成功后在执行下面逻辑
            final CountDownLatch countDownLatch = new CountDownLatch(1);
            //连接成功后，会回调watcher监听，此连接操作是异步的，执行完new语句后，直接调用后续代码
            zooKeeper = new ZooKeeper(connectString, timeout, event -> {
                log.info("接受到watcher通知:{}",event);
                if(Watcher.Event.KeeperState.SyncConnected==event.getState()){
                    //如果收到了服务端的响应事件,连接成功
                    countDownLatch.countDown();
                }
            });
            countDownLatch.await();
            log.info("【初始化ZooKeeper连接状态....】={}",zooKeeper.getState());

        }catch (Exception e){
            log.error("初始化ZooKeeper连接异常....】={}",e);
        }
        return  zooKeeper;
    }
}
